mod typeval;

use std::collections::HashMap;

fn main() {
    println!("Hello, world!");
    // -------------------------------

    // 1. 标量类型 (Scalar Types)

    // -------------------------------

    // 整数类型 - 默认推导为 i32

    let integer: i32 = -42; // 有符号整数

    let unsigned: u32 = 1024; // 无符号整数

    // 浮点类型 - 默认推导为 f64

    let float: f64 = std::f64::consts::PI; // 双精度浮点

    // 布尔类型

    let is_rust_cool: bool = true;

    // 字符类型 (Unicode 标量)

    let emoji: char = '🚀';

    // let  x: i32 = 100;
    let mut x: i32 = 100;
    x = 101;

    // -------------------------------

    // 打印所有值

    // -------------------------------

    println!("整数: {} (有符号), {} (无符号)", integer, unsigned);

    println!("浮点数: {:.2} (保留两位小数)", float); // 格式化输出

    println!("布尔值: {}", is_rust_cool);

    println!("字符: {}", emoji);
    println!("变量 x: {}", x);

    // 复合类型
    // 数组 固定长度 类型相同
    let arr: [i32; 5] = [1, 2, 3, 4, 5];
    println!("数组元素: {:?}", arr);
    println!("数组元素: {}", arr[0]);
    let arr_len = arr.len();
    println!("数组长度: {}", arr_len);
    // 元组 固定长度 类型不同
    let tup: (i32, f64, char) = (100, 3.14, 'a');
    println!("元组元素: {:?}", tup);
    let (x, y, z) = tup;
    println!("元组解构: {}, {}, {}", x, y, z);
    println!("元组索引: {}, {}, {}", tup.0, tup.1, tup.2);

    // 字符串 切片 不可变视图
    let str1: &str = "Hello, Rust!";
    println!("字符串切片: {}", str1);
    // 字符串 切片 可变视图 可增长的堆分配字符串
    let mut str2: String = String::from("Hello, World!");
    println!("字符串: {}", str2);
    str2.push_str(", Rust");
    println!("字符串: {}", str2);
    str2.push(',');
    println!("字符串: {}", str2);
    str2.push('!');
    println!("字符串: {}", str2);

    // 动态数组
    let vec: Vec<i32> = vec![1, 2, 3, 4, 5];
    println!("动态数组元素: {:?}", vec);
    println!("动态数组长度: {}", vec.len());
    println!("动态数组元素: {}", vec[0]);
    println!("动态数组元素: {}", vec.get(0).unwrap());
    // 动态数组元素 越界处理
    println!("动态数组元素: {}", vec.get(10).unwrap_or(&-1));

    // let  mut  subject_list = vec!["Rust", "Python"];
    // subject_list.push("Java");
    // println!("动态数组元素: {:?}", subject_list);
    // 声明一个vec, 这里可以不指明数据类型，在具体使用时，编译器会自动推断
    let mut subject_list = vec![];
    subject_list.push("Rust");
    subject_list.push("Python");
    subject_list.push("Java");
    println!("动态数组元素: {:?}", subject_list);
    let mut vector: Vec<i32> = vec![1, 2, 4, 8];
    vector.push(16);
    vector.push(32);
    vector.push(64);
    println!("{:?}", vector);
    // 遍历 不可变 引用 后面可以使用 &i32, 但是不能使用 &mut i32
    for i in &vector {
        println!("{}", i);
    }
    // 可变引用 遍历 后面可以使用 &mut i32, 但是不能使用 &i32
    for i in &mut vector {
        *i *= 2;
        println!("{}", i);
    }
    // 所有权转移 所有权转移后，不能再使用原来的变量
    for i in vector {
        println!("{}", i);
    }

    // 哈希表
    let mut hash_map = std::collections::HashMap::new();
    hash_map.insert("Rust", "A programming language");
    hash_map.insert("Python", "Another programming language");
    println!("{:?}", hash_map);
    println!("{}", hash_map.get("Rust").unwrap());
    println!("{:?}", hash_map.get("Java"));
    println!("{:?}", hash_map.get("Java").unwrap_or(&"Not found"));
    for (key, value) in &hash_map {
        println!("{}: {}", key, value);
    }
    for (key, value) in &mut hash_map {
        *value = "A programming language in high demand";
        println!("{}: {}", key, value);
    }
    for (key, value) in hash_map {
        println!("{}: {}", key, value);
    }
    let mut year: HashMap<i32, String> = HashMap::new();

    year.insert(2000, "龙".to_string()); // 字符串切片转为String

    year.insert(2025, "蛇".to_string());

    println!("year: {:?}", year);

    let mut pass: HashMap<&str, bool> = HashMap::new();

    pass.insert("iceymoss", true);

    pass.insert("lass", false);

    pass.remove("lass");

    println!("pass: {:?}", pass);

    println!("len: {}", pass.len());

    println!("key: {:?}", pass.keys());

    println!("value: {:?}", pass.values());

    // 结构体类型
    struct Person1 {
        name: String,
        age: i32,
    }
    let person1 = Person1 {
        name: "Alice".to_string(),
        age: 30,
    };
    println!("{} is {} years old", person1.name, person1.age);

    // 定义一个坐标
    struct Point {
        x: f32,
        y: f32,
    }

    // 定义一个居住信息
    struct Live {
        name: String,
        point: Point,
    }

    // 定义一个个人信息

    struct Person {
        name: String,
        age: u8,
        likes: u8,
        gender: u8,
        live: Live,
    }

    // 实例化一个Person

    let ming: Person = Person {
        name: "iceymoss".to_string(),
        age: 20,
        likes: 5,
        gender: 1,
        live: Live {
            // 实例化
            name: "ShangHai".to_string(),
            point: Point {
                x: 123.32,
                y: 38.2374,
            }, // 实例化
        },
    };

    println!("ming.name = {}", ming.name);

    println!("ming.age = {}", ming.age);

    println!("ming.likes = {}", ming.likes);

    println!("ming.gender = {}", ming.gender);

    println!("ming.live.name = {}", ming.live.name);

    println!("ming.points.x = {}", ming.live.point.x);

    println!("ming.points.y = {}", ming.live.point.y);

    // 元组结构体
    struct Color2(i32, i32, i32);
    let red = Color2(255, 0, 0);
    println!("Red: ({}, {}, {})", red.0, red.1, red.2);
    // 单元结构体
    // 用于自动为结构体、枚举等类型实现std::fmt::Debug trait。
    // 这个trait提供了format!宏的{:?}占位符所需的功能，允许类型以易读的格式打印其值，主要用于调试目的。
    #[derive(Debug)]
    struct Empty;
    let empty = Empty;
    println!("{:?}", empty);

    // 枚举类型
    #[derive(Debug)]
    enum Color {
        Red,
        Green,
        Blue,
    }
    // 使用枚举类型 声明
    let color = Color::Red;
    println!("{:?}", color);
    match color {
        Color::Red => println!("Red"),
        Color::Green => println!("Green"),
        Color::Blue => println!("Blue"),
    }
    // 枚举类型 带数据
    #[derive(Debug)]
    enum Color1 {
        Red(i32, i32, i32),
        Green(i32, i32, i32),
        Blue(i32, i32, i32),
    }
    let red = Color1::Red(255, 0, 0);
    println!("{:?}", red);
    match red {
        Color1::Red(r, g, b) => println!("Red: ({}, {}, {})", r, g, b),
        _ => (),
    }

    // 枚举类型 带数据
    enum Book {
        Papery { index: u32 },      // 变体中定义了u32类型的一个索引，表示书的页号
        Electronic { url: String }, // 变体中定义了一个String类型的url，表示电子书的链接
    }
    let book = Book::Papery { index: 1001 };

    let ebook = Book::Electronic {
        url: String::from("http://mybook.com/electronic/bookname/index.html"),
    };

    match book {
        Book::Papery { index } => println!("Paper book index: {}", index),
        _ => (),
    }
    match ebook {
        Book::Electronic { url } => println!("Ebook url: {}", url),
        _ => (),
    }

    // Option枚举
    // enum Option<T> {
    //     None,
    //     Some(T),
    // }
    let some_number = Some(5);
    match some_number {
        Some(n) => println!("Some number: {}", n),
        None => println!("No number"),
    }
    let no_number: Option<i32> = None;
    match no_number {
        Some(n) => println!("Some number: {}", n),
        None => println!("No number"),
    }
    let opt = Option::Some("Hello");

    match opt {
        Option::Some(something) => {
            println!("{}", something);
        }

        Option::None => {
            println!("opt is nothing");
        }
    }
    // if let 语法
    if let Some(n) = some_number {
        println!("Some number: {}", n);
    } else {
        println!("No number");
    }
    // Result枚举
    // enum Result<T, E> {
    //     Ok(T),
    //     Err(E),
    // }
    // let  result = Result::Ok(5);
    // match result {
    //     Result::Ok(n) => println!("Success: {}", n),
    //     Result::Err(e) => println!("Error: {:?}", e),
    // }
    // let error = Result::Err("Error message");
    // match error {
    //     Result::Ok(n) => println!("Success: {}", n),
    //     Result::Err(e) => println!("Error: {:?}", e),
    // }
    // // if let 语法
    // if let Result::Ok(n) = result {
    //     println!("Success: {}", n);
    // } else if let Result::Err(e) = error {
    //     println!("Error: {:?}", e);
    // }
    // 控制流
    let mut count = 0;
    loop {
        count += 1;
        if count == 10 {
            break;
        }
        println!("Count: {}", count);
    }
    let mut count = 0;
    while count < 10 {
        println!("Count: {}", count);
        count += 1;
    }
    for i in 0..10 {
        println!("Count: {}", i);
    }
    for i in 0..10 {
        if i % 2 == 0 {
            continue;
        }
        println!("Count: {}", i);
    }
    for i in 0..10 {
        if i == 5 {
            break;
        }
        println!("Count: {}", i);
    }
    let mut count = 0;
    'outer: loop {
        'inner: loop {
            count += 1;
            if count == 5 {
                break 'outer;
            }
            println!("Count: {}", count);
        }
    }

    // 方法使用
    struct Point2 {
        x: i32,
        y: i32,
    }
    impl Point2 {
        // 关联函数，用于创建新的Point实例，不是方法，因为它不接受self参数 (self: &Self 或 self: Box<Self> 等)
        fn new(x: i32, y: i32) -> Point2 {
            Point2 { x, y }
        }
        // 实例方法，接受self参数 (self: &Self) 来访问实例的字段或调用其他方法 (self: &mut Self) 来修改实例
        fn distance(&self, other: &Point2) -> f64 {
            let dx = self.x as f64 - other.x as f64;
            let dy = self.y as f64 - other.y as f64;
            ((dx * dx) + (dy * dy)).sqrt()
        }
    }
    let p1 = Point2::new(0, 0);
    let p2 = Point2::new(5, 5);
    println!("Distance: {}", p1.distance(&p2));

    // 模块使用mod
    mod my_module {
        // 公有函数，可以在其他模块中访问
        pub fn public_function() {
            println!("Public function");
            // 调用私有函数 同一模块的私有函数
            private_function();
            // 调用私有子模块函数 只能是公共函数
            sub_private_module::call_private2();
            sub_public_module::sub_pub_function();
        }
        // 私有函数，只能在同一模块内访问
        fn private_function() {
            println!("Private function");
        }
        // 公共子模块
        pub mod sub_public_module {
            pub fn sub_pub_function() {
                println!("Sub function");
            }
            // 调用私有函数
            // private_function(); // 错误，私有函数不能直接访问
            // 但可以通过公有函数间接访问
            pub fn call_private() {
                super::private_function(); // 通过 super 关键字访问父模块的私有函数
            }
            // 私有函数
            fn sub_private_function() {
                println!("Private function");
            }
        }
        // 调用私有函数
        pub fn call_sub() {
            sub_public_module::call_private();
            // 私有函数不能直接访问
            // sub_public_module::sub_private_function();
            // 私有子模块 的公共方法
            sub_private_module::call_private2();
        }

        // 私有子模块
        mod sub_private_module {
            // 函数虽标记为 pub，但受模块可见性限制
            pub fn sub_pub_function2() {
                println!("Sub function2");
            }
            // 调用私有函数
            pub fn call_private2() {
                // 可以调用父模块的私有函数
                super::private_function(); // 通过 super 关键字访问父模块的私有函数
                sub_pub_function2();
                // 可以调用兄弟模块 的方法
                super::sub_public_module::call_private();
            }
        }
    }
    my_module::public_function();
    // my_module::private_function(); // 错误，私有函数不能直接访问

    // trait 使用
    trait Animal {
        fn speak(&self);
    }
    struct Dog;
    impl Animal for Dog {
        fn speak(&self) {
            println!("Woof!");
        }
    }
    let dog = Dog;
    dog.speak();
    // 默认实现
    trait Animal2 {
        fn speak(&self) {
            println!("Some generic sound");
        }
    }
    struct Cat;
    impl Animal2 for Cat {}
    let cat = Cat;
    cat.speak();
    // 默认实现可以被覆盖
    trait Animal3 {
        fn speak(&self) -> String {
            String::from("Some generic sound")
        }
    }
    struct Bird;
    impl Animal3 for Bird {
        // 覆盖默认实现
        fn speak(&self) -> String {
            String::from("Tweet!")
        }
    }
    let bird = Bird;
    println!("{}", bird.speak());
    // 泛型
    struct Point3<T> {
        x: T,
        y: T,
    }
    impl<T> Point3<T> {
        fn new(x: T, y: T) -> Point3<T> {
            Point3 { x, y }
        }
    }
    let int_point = Point3::new(10, 20);
    let float_point = Point3::new(10.5, 20.5);
    println!("Int Point: ({}, {})", int_point.x, int_point.y);
    println!("Float Point: ({}, {})", float_point.x, float_point.y);
    // 生命周期
    fn longest<'a>(x: &'a str, y: &'a str) -> &'a str {
        if x.len() > y.len() { x } else { y }
    }
    let string1 = "abcd";
    let result = longest(string1, "xyz");
    println!("The longest string is: {}", result);
    // 闭包
    fn apply<F: FnOnce()>(f: F) {
        f();
    }
    apply(|| println!("This is a closure"));
    // 宏
    macro_rules! my_macro {
        ($x:expr) => {
            $x
        };
    }
    let value = 10;
    println!("{}", my_macro!(value));
    // 错误处理
    fn divide(a: f64, b: f64) -> Result<f64, String> {
        if b == 0.0 {
            Err("Cannot divide by zero".to_string())
        } else {
            Ok(a / b)
        }
    }
    match divide(10.0, 2.0) {
        Ok(result) => println!("Result: {}", result),
        Err(err) => println!("Error: {}", err),
    }
    // 并发
    use std::thread;
    let handle = thread::spawn(|| {
        println!("Hello from a new thread!");
    });
    handle.join().unwrap();
    // 智能指针
    use std::rc::Rc;
    let a = Rc::new(5);
    let b = Rc::clone(&a);
    println!("Count after cloning: {}", Rc::strong_count(&a));
    println!("Value of a: {}", *a);
    println!("Value of b: {}", *b);
    // // 测试
    // #[cfg(test)]
    // mod tests {
    //     use super::*;
    //     #[test]
    //     fn test_divide() {
    //         assert_eq!(divide(10.0, 2.0).unwrap(), 5.0);
    //         assert_eq!(divide(10.0, 0.0).is_err(), true);
    //     }
    // }
    // // 运行测试
    // #[cfg(test)]
    // fn main() {
    //     println!("Running tests...");
    //     let result = test::run_tests();
    //     if result.is_ok() {
    //         println!("All tests passed!");
    //     } else {
    //         println!("Some tests failed.");
    //     }
    // }
    use typeval::type_val;
    type_val();


}
